﻿using System.ComponentModel;
using MyFramework.Command.Interfaces;

namespace MyFramework.Command.DelegateWatchCommand
{
    /// <summary>
    /// Property watch tail
    /// </summary>
    public class PropertyWatchTail : IPropertyWatchTail
    {
        #region Fields

        /// <summary>
        /// The prop name
        /// </summary>
        private string propName;

        /// <summary>
        /// The source
        /// </summary>
        private INotifyPropertyChanged source;

        #endregion

        #region constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="PropertyWatchTail"/> class.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        public PropertyWatchTail(string propertyName)
        {
            propName = propertyName;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the parent.
        /// </summary>
        /// <value>
        /// The parent.
        /// </value>
        public PropertyWatchChain Parent { get; set; }

        /// <summary>
        /// Gets the name of the property.
        /// </summary>
        /// <value>
        /// The name of the property.
        /// </value>
        public string PropertyName
        {
            get { return propName; }
        }

        /// <summary>
        /// Gets or sets the source.
        /// </summary>
        /// <value>
        /// The source.
        /// </value>
        public INotifyPropertyChanged Source
        {
            get { return source; }
            set
            {
                if (source != value)
                {
                    if (source != null)
                    {
                        source.PropertyChanged -= new PropertyChangedEventHandler(source_PropertyChanged);
                        source = value;
                        source.PropertyChanged += new PropertyChangedEventHandler(source_PropertyChanged);
                    }
                    else
                    {
                        source = value;
                    }

                    this.OnWatchedPropertyChanged(null);
                }
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Handles the PropertyChanged event of the source control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.PropertyChangedEventArgs"/> instance containing the event data.</param>
        void source_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            this.OnWatchedPropertyChanged(e.PropertyName);
        }

        /// <summary>
        /// Doesnt copy Source. 
        /// </summary>
        /// <returns></returns>
        public IPropertyWatchTail Clone()
        {
            return new PropertyWatchTail(this.PropertyName);
        }

        /// <summary>
        /// Called when [watched property changed].
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        private void OnWatchedPropertyChanged(string propertyName)
        {
            if (propertyName == null || propName == null || propertyName == propName)
            {
                if (this.Parent != null)
                {
                    this.Parent.OnWatchedPropertyChanged();
                }
            }
        }

        /// <summary>
        /// Gets the tail.
        /// </summary>
        /// <returns></returns>
        public IPropertyWatchTail GetTail()
        {
            return this;
        }

        #endregion
    }
}
